home *** CD-ROM | disk | FTP | other *** search
- /*
- * $RCSfile: lock.c,v $
- * $Revision: 1.1.1.1 $
- * $Date: 1996/05/04 21:55:51 $
- */
- /**********************************************************************
- * EXODUS Database Toolkit Software
- * Copyright (c) 1991 Computer Sciences Department, University of
- * Wisconsin -- Madison
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
- * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.
- * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
- * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * The EXODUS Project Group requests users of this software to return
- * any improvements or extensions that they make to:
- *
- * EXODUS Project Group
- * c/o David J. DeWitt and Michael J. Carey
- * Computer Sciences Department
- * University of Wisconsin -- Madison
- * Madison, WI 53706
- *
- * or exodus@cs.wisc.edu
- *
- * In addition, the EXODUS Project Group requests that users grant the
- * Computer Sciences Department rights to redistribute these changes.
- **********************************************************************/
-
- #include "sysdefs.h"
- #include "ess.h"
- #include "checking.h"
- #include "trace.h"
- #include "error.h"
- #include "list.h"
- #include "pool.h"
- #include "tid.h"
- #include "io.h"
- #include "lock.h"
- #include "object.h"
- #include "msgdefs.h"
- #include "thread.h"
- #include "semaphore.h"
- #include "link.h"
- #include "lsn.h"
- #include "latch.h"
- #include "bf.h"
- #include "volume.h"
- #include "trans.h"
- #include "lm_intfuncs.h"
- #include "lm_extfuncs.h"
- #include "lm_globals.h"
- #include "lock_globals.h"
- #include "thread_globals.h"
-
-
- int
- lock (
-
- register TRANSREC *transRec,
- register LOCKID *lockid,
- register LOCKMODE *lockMode, /* IN/OUT */
- FLAGS flags,
- int timeOut,
- int weight
- )
- {
-
- register LOCKHEADER *lockHeader;
- register LOCKENTRY *lockEntry;
- int slot;
- LOCKMODE requestMode = *lockMode;
-
- TRPRINT(TR_LOCK, TR_LEVEL_1, ("object:%x:%x:%x tid:%x requestMode:%s",
- lockid->lockid.word1, lockid->lockid.word2, lockid->lockid.word3,
- GETTID(transRec), GETMODE(requestMode)));
-
- /*
- * check to see the state of the transaction
- */
- if ((transRec->transState != T_ACTIVE) &&
- (transRec->transState != T_PREPARED)) {
-
- SM_ERROR(TYPE_USER, esmBADTRANSID);
- return(esmFAILURE);
- }
-
- /*
- * check the request mode to make sure this is a valid request
- */
- SM_ASSERT(LEVEL_3, (requestMode >= MIN_LOCK_MODE) && (requestMode <= MAX_LOCK_MODE));
-
- /*
- * get the slot that the lockid will hash to
- */
- slot = hashLockId(lockid);
-
- /*
- * Get a lock header structure
- */
- if ((lockHeader = findLockHeader(lockid, slot)) == NULL) {
-
- TRPRINT(TR_LOCK, TR_LEVEL_2, ("object not locked"));
-
- /*
- * check to see if this is a request for an instant lock
- */
- if (flags & LOCK_INSTANT) {
-
- return(esmNOERROR);
- }
-
- /*
- * get a lock header record
- */
- if ((lockHeader = (LOCKHEADER *) poolDeq( &LockHeaderPool )) == NULL) {
-
- /*
- * set the error code and return
- */
- SM_ERROR(TYPE_WARNING, esmNOFREELOCKHEADER);
- return(esmFAILURE);
- }
- CHECK_LOCKHEADER_MAGIC(lockHeader);
-
- /*
- * initialize the lock header fields
- */
- initLockHeader(lockHeader);
-
- /*
- * get a lock entry record and initialize and queue it
- */
- if ((lockEntry =
- newLockEntry(transRec, lockHeader, GRANT_LIST,requestMode))==NULL){
-
- /*
- * return the lock header
- */
- poolEnq( &LockHeaderPool, &(lockHeader->hashList.list) );
-
- /*
- * return the error code
- */
- return(esmFAILURE);
- }
-
- /*
- * initialize the fields of the lock header
- */
- lockHeader->hashList.lockid = *lockid;
- lockHeader->modeCount[requestMode] = 1;
- lockHeader->supremum = requestMode;
- listPush( &(LockHashTable[slot]), &(lockHeader->hashList.list) );
-
- /*
- * initialize the fields of the lock entry
- */
- lockEntry->weight = weight;
-
- TRPRINT(TR_LOCK, TR_LEVEL_1,
- ("Thread %d, running for trans %ld, is ALLOCating a %s (flag %d) lock (id %s) entry for trans %d",
- Active->id, Active->message.header.params.in.tid,
- GETMODE(lockEntry->lockMode), (int)lockEntry->flags,
- lockEntry->flags & LOCK_UPGRADE ?
- printLockId(((LOCKENTRY*)lockEntry->lockHeader)->lockHeader->hashList.lockid) :
- printLockId(lockEntry->lockHeader->hashList.lockid),
- lockEntry->headerList.transRec->tid) );
-
-
- /*
- * update the weight in the transaction record
- */
- transRec->lockWeight += weight;
-
- /*
- * return success
- */
- CHECK_LOCKHEADER_MAGIC(lockHeader);
- return(esmNOERROR);
-
- } else {
-
- TRPRINT(TR_LOCK, TR_LEVEL_2, ("found lock header"));
-
- CHECK_LOCKHEADER_MAGIC(lockHeader);
-
- /*
- * put the lock on the top of the queue for better performance
- */
- listMovePush( &(LockHashTable[slot]), &(lockHeader->hashList.list) );
-
- /*
- * check to see if this transaction holds a lock
- */
- if ((lockEntry = findLockEntry( &(lockHeader->grantedList) , transRec)) != NULL) {
-
- TRPRINT(TR_LOCK, TR_LEVEL_2, ("lock held by transaction"));
-
- /*
- * check to see if request mode is compatible with
- * the mode currently held by this transaction
- */
- if (LM_Compat_Upgrade[requestMode][lockEntry->lockMode]) {
-
- /*
- * The lock is compatible so there is no reason to
- * upgrade, so just return the current mode
- */
- TRPRINT(TR_LOCK, TR_LEVEL_2, ("lock is compatible"));
- *lockMode = lockEntry->lockMode;
- return(esmNOERROR);
-
- } else {
-
- /*
- * attempt to upgrade the lock
- */
- if (upgradeLock(transRec, lockHeader, lockEntry, requestMode, flags) != esmNOERROR) {
- return(esmFAILURE);
- } else {
- /* return the lock mode upgraded to */
- *lockMode = lockEntry->lockMode;
- }
- }
-
- } else {
-
- TRPRINT(TR_LOCK, TR_LEVEL_2, ("lock not held by transaction"));
-
- /*
- * attempt to give the lock
- */
- if ((lockEntry = heldLockEntry(transRec, lockHeader,
- requestMode, flags)) == NULL) {
-
- return(esmFAILURE);
-
- } else {
-
- /*
- * increment the weights
- */
- lockEntry->weight = weight;
- transRec->lockWeight += weight;
- return(esmNOERROR);
- }
- }
- }
- return(esmNOERROR);
- }
-